package com.lh.item.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lh.common.pojo.PageResult;
import com.lh.item.bo.SpuBo;
import com.lh.item.mapper.*;
import com.lh.item.pojo.*;
import com.lh.item.service.ICategoryService;
import com.lh.item.service.IGoodsService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class GoodsServiceImpl implements IGoodsService {

    final SpuMapper spuMapper;
    final ICategoryService iCategoryService;
    final BrandMapper brandMapper;
    final SpuDetailMapper spuDetailMapper;
    final SkuMapper skuMapper;
    final StockMapper stockMapper;

    @Autowired
    public GoodsServiceImpl(SpuMapper spuMapper, ICategoryService iCategoryService, BrandMapper brandMapper,
                            SpuDetailMapper spuDetailMapper, SkuMapper skuMapper, StockMapper stockMapper) {
        this.spuMapper = spuMapper;
        this.iCategoryService = iCategoryService;
        this.brandMapper = brandMapper;
        this.spuDetailMapper = spuDetailMapper;
        this.skuMapper = skuMapper;
        this.stockMapper = stockMapper;
    }

    @Override
    public PageResult<SpuBo> getSpuList(Integer page, Integer rows, String key, Boolean saleable) {
        Example example = new Example(SpuDo.class);
        Example.Criteria criteria = example.createCriteria();
        // 搜索条件
        if (!StringUtils.isEmpty(key)) {
            criteria.andLike("title", "%" + key + "%");
        }

        if (null != saleable) {
            criteria.andEqualTo("saleable", saleable);
        }
        //分页查询
        PageHelper.startPage(page, rows);
        List<SpuDo> spuses = this.spuMapper.selectByExample(example);
        PageInfo<SpuDo> pageInfo = new PageInfo<>(spuses);

        ArrayList<SpuBo> spuBos = new ArrayList<>();
        spuses.forEach((it) -> {
            SpuBo spuBo = new SpuBo();
            // copy共同属性的值到新的对象
            BeanUtils.copyProperties(it, spuBo);
            // 查询商品分类
            List<Long> cids = Arrays.asList(it.getCid1(), it.getCid2(), it.getCid3());
            List<String> names = this.iCategoryService.queryNamesByIds(cids);
            spuBo.setCname(org.apache.commons.lang.StringUtils.join(names, "/"));
            // 查询商品品牌
            spuBo.setBname(this.brandMapper.selectByPrimaryKey(it.getBrandId()).getName());
            spuBos.add(spuBo);
        });
        return new PageResult<SpuBo>(pageInfo.getTotal(), pageInfo.getPageSize(), pageInfo.getPageNum(), spuBos);
    }

    @Override
    public SpuDetailDo getSpuDetailBySpuId(Long spuId) {
        SpuDetailDo spuDetailDo = this.spuDetailMapper.selectByPrimaryKey(spuId);
        return spuDetailDo;
    }

    @Override
    public SpuBo querySpuById(Long spuId) {
        SpuDo spuDo = this.spuMapper.selectByPrimaryKey(spuId);
        SpuDetailDo spuDetailDo = this.spuDetailMapper.selectByPrimaryKey(spuId);
        Example example = new Example(SkuDo.class);
        example.createCriteria().andEqualTo("spuId", spuDo.getId());
        List<SkuDo> skuDos = this.skuMapper.selectByExample(example);

        ArrayList<Long> skuIdList = new ArrayList<>();
        skuDos.forEach(skuDo -> skuIdList.add(skuDo.getId()));
        List<StockDo> stockDos = this.stockMapper.selectByIdList(skuIdList);

        for (SkuDo skuDo : skuDos) {
            for (StockDo stockDo : stockDos) {
                if (skuDo.getId().equals(stockDo.getSkuId())) {
                    skuDo.setStock(stockDo.getStock());
                }
            }
        }

        SpuBo spuBo = new SpuBo(spuDo.getBrandId(), spuDo.getCid1(), spuDo.getCid2(), spuDo.getCid3(), spuDo.getTitle(),
                spuDo.getSubTitle(), spuDo.getSaleable(), spuDo.getValid(), spuDo.getCreateTime(), spuDo.getLastUpdateTime());

        spuBo.setSpuDetailDo(spuDetailDo);
        spuBo.setSkus(skuDos);
        return spuBo;
    }

    @Override
    @Transactional
    public boolean addGoods(SpuBo spuBo) {
        try {
            // // 新增spu
            spuBo.setId(null);
            spuBo.setSaleable(true);
            spuBo.setValid(true);
            spuBo.setCreateTime(new Date());
            spuBo.setLastUpdateTime(spuBo.getCreateTime());
            // insert null也保存，insetSelective null值使用数据库默认值
            this.spuMapper.insertSelective(spuBo);

            // spu detail保存
            SpuDetailDo spuDetailDo = spuBo.getSpuDetailDo();
            spuDetailDo.setSpuId(spuBo.getId());
            this.spuDetailMapper.insertSelective(spuDetailDo);

            // sku保存
            saveSkuAndStock(spuBo);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    @Transactional
    public boolean updateGoods(SpuBo spuBo) {
        try {
//            spu数据可以修改，但是SKU数据无法修改，因为有可能之前存在的SKU现在已经不存在了，
//            或者以前的sku属性都不存在了。比如以前内存有4G，现在没了。因此这里直接删除以前的SKU，然后新增即可。
            List<SkuDo> skuList = this.getSkuListBySpuId(spuBo.getId());
            if (!CollectionUtils.isEmpty(skuList)) {
                // 删除库存
                List<Long> ids = skuList.stream().map(s -> s.getId()).collect(Collectors.toList());
                Example example = new Example(StockDo.class);
                example.createCriteria().andIn("skuId", ids);
                this.stockMapper.deleteByExample(example);
                // 删除以前的sku
                SkuDo skuDo = new SkuDo();
                skuDo.setSpuId(spuBo.getId());
                this.skuMapper.delete(skuDo);
            }

            // 更新spu
            spuBo.setLastUpdateTime(new Date());
            this.spuMapper.updateByPrimaryKeySelective(spuBo);
            // 更新spu详情
            this.spuDetailMapper.updateByPrimaryKeySelective(spuBo.getSpuDetailDo());
            // 更新sku列表和库存
            saveSkuAndStock(spuBo);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    @Override
    public List<SkuDo> getSkuListBySpuId(Long spuId) {
        SkuDo skuDo = new SkuDo();
        skuDo.setSpuId(spuId);
        List<SkuDo> skuList = this.skuMapper.select(skuDo);
        return skuList;
    }

    private void saveSkuAndStock(SpuBo spuBo) {
        List<SkuDo> skus = spuBo.getSkus();
        skus.forEach(sku -> {
            // sku绑定spuId
            sku.setSpuId(spuBo.getId());
            sku.setCreateTime(new Date());
            sku.setLastUpdateTime(sku.getCreateTime());
            this.skuMapper.insertSelective(sku);

            // 库存信息
            StockDo stockDo = new StockDo();
            stockDo.setSkuId(sku.getId());
            stockDo.setStock(sku.getStock());
            this.stockMapper.insertSelective(stockDo);
        });
    }

}
